package fairygui.editor.gui
{
   import fairygui.editor.gui.text.EHtmlElement;
   import fairygui.editor.gui.text.EHtmlNode;
   import fairygui.editor.gui.text.EHtmlText;
   import fairygui.editor.gui.text.ELinkButton;
   import fairygui.editor.utils.UtilsStr;
   import fairygui.utils.CharSize;
   import fairygui.utils.UBBParser;
   import flash.display.Sprite;
   import flash.events.Event;
   import flash.geom.Rectangle;
   import flash.text.TextFormat;
   import flash.text.TextLineMetrics;
   
   public class EGRichTextField extends EGTextField
   {
       
      
      private var _lineInfo:Array;
      
      private var _linkButtonCache:Vector.<ELinkButton>;
      
      private var _nodeCache:Vector.<EHtmlNode>;
      
      private var _needUpdateNodePos:Boolean;
      
      private var _ALinkFormat:TextFormat;
      
      private var _AHoverFormat:TextFormat;
      
      private var _objectsContainer:Sprite;
      
      public function EGRichTextField()
      {
         super();
         this.objectType = ObjectTypes.RICHTEXT;
         this._linkButtonCache = new Vector.<ELinkButton>();
         this._nodeCache = new Vector.<EHtmlNode>();
         this._ALinkFormat = new TextFormat();
         this._ALinkFormat.underline = true;
         this._AHoverFormat = new TextFormat();
         this._AHoverFormat.underline = true;
         this._objectsContainer = new Sprite();
         this._objectsContainer.mouseEnabled = false;
         _displayObject.container.addChild(this._objectsContainer);
         this._lineInfo = [];
      }
      
      public function updateRichText() : void
      {
         var _loc5_:int = 0;
         var _loc7_:EHtmlElement = null;
         var _loc8_:int = 0;
         var _loc9_:int = 0;
         var _loc10_:EPackageItem = null;
         this.clear();
         if(!_text.length)
         {
            this.fixTextSize();
            return;
         }
         var _loc1_:String = _text;
         if(_ubbEnabled)
         {
            _loc1_ = UBBParser.inst.parse(_loc1_);
         }
         var _loc2_:EHtmlText = new EHtmlText(_loc1_);
         _textField.defaultTextFormat = _textFormat;
         var _loc3_:int = _textField.text.length;
         var _loc4_:String = _loc2_.parsedText;
         _textField.replaceText(_loc3_,_loc3_,_loc4_);
         var _loc6_:int = _loc2_.elements.length;
         _loc5_ = _loc6_ - 1;
         while(_loc5_ >= 0)
         {
            _loc7_ = _loc2_.elements[_loc5_];
            if(_loc7_.type == EHtmlElement.LINK)
            {
               if(this._ALinkFormat)
               {
                  _textField.setTextFormat(this._ALinkFormat,_loc3_ + _loc7_.start,_loc3_ + _loc7_.end + 1);
               }
            }
            else if(_loc7_.type == EHtmlElement.IMAGE)
            {
               _loc8_ = 20;
               _loc9_ = 20;
               if(UtilsStr.startsWith(_loc7_.src,"ui://"))
               {
                  _loc10_ = this.pkg.project.getItemByURL(_loc7_.src);
                  if(_loc10_ != null)
                  {
                     _loc8_ = _loc10_.width;
                     _loc9_ = _loc10_.height;
                  }
               }
               if(_loc7_.width == 0)
               {
                  _loc7_.realWidth = _loc8_;
               }
               else
               {
                  _loc7_.realWidth = _loc7_.width;
               }
               if(_loc7_.height == 0)
               {
                  _loc7_.realHeight = _loc9_;
               }
               else
               {
                  _loc7_.realHeight = _loc7_.height;
               }
               _loc7_.textformat.font = !!_textField.embedFonts?_textFormat.font:CharSize.PLACEHOLDER_FONT;
               _loc7_.textformat.size = _loc7_.realHeight + 2;
               _loc7_.textformat.underline = false;
               _loc7_.textformat.letterSpacing = _loc7_.realWidth + 4 - CharSize.getHolderWidth(_loc7_.textformat.font,_loc7_.realHeight + 2);
               _textField.setTextFormat(_loc7_.textformat,_loc3_ + _loc7_.start,_loc3_ + _loc7_.end + 1);
            }
            else
            {
               _textField.setTextFormat(_loc7_.textformat,_loc3_ + _loc7_.start,_loc3_ + _loc7_.end + 1);
            }
            _loc5_--;
         }
         this.fixTextSize();
         _loc5_ = 0;
         while(_loc5_ < _loc6_)
         {
            _loc7_ = _loc2_.elements[_loc5_];
            if(_loc7_.type == EHtmlElement.LINK)
            {
               this.addLink(_loc3_,_loc7_);
            }
            else if(_loc7_.type == EHtmlElement.IMAGE)
            {
               this.addImage(_loc3_,_loc7_);
            }
            _loc5_++;
         }
         if(_displayObject.stage == null && !this._needUpdateNodePos)
         {
            this._needUpdateNodePos = true;
            _displayObject.addEventListener(Event.ADDED_TO_STAGE,this.__addedToStage,false,0,true);
         }
      }
      
      override protected function handleDispose() : void
      {
         super.handleDispose();
         this.resetLines();
      }
      
      private function __addedToStage(param1:Event) : void
      {
         if(!this._needUpdateNodePos)
         {
            return;
         }
         this.adjustNodes();
         this._needUpdateNodePos = false;
      }
      
      private function adjustNodes() : void
      {
         var _loc3_:Object = null;
         var _loc4_:int = 0;
         var _loc5_:int = 0;
         var _loc6_:EHtmlNode = null;
         var _loc1_:int = this._lineInfo.length;
         var _loc2_:int = 0;
         while(_loc2_ < _loc1_)
         {
            _loc3_ = this._lineInfo[_loc2_];
            if(_loc3_)
            {
               _loc4_ = _loc3_.length;
               if(this.isLineVisible(_loc2_))
               {
                  _loc5_ = 0;
                  while(_loc5_ < _loc4_)
                  {
                     _loc6_ = _loc3_[_loc5_];
                     if(this._needUpdateNodePos)
                     {
                        _loc6_.posUpdated = false;
                     }
                     this.showNode(_loc6_);
                     _loc5_++;
                  }
               }
               else
               {
                  _loc5_ = 0;
                  while(_loc5_ < _loc4_)
                  {
                     _loc6_ = _loc3_[_loc5_];
                     if(this._needUpdateNodePos)
                     {
                        _loc6_.posUpdated = false;
                     }
                     this.hideNode(_loc6_);
                     _loc5_++;
                  }
               }
            }
            _loc2_++;
         }
      }
      
      private function resetLines() : void
      {
         var _loc3_:Vector.<EHtmlNode> = null;
         var _loc4_:int = 0;
         var _loc5_:EHtmlNode = null;
         var _loc1_:int = this._lineInfo.length;
         var _loc2_:int = 0;
         while(_loc2_ < _loc1_)
         {
            _loc3_ = this._lineInfo[_loc2_];
            if(_loc3_)
            {
               _loc4_ = 0;
               while(_loc4_ < _loc3_.length)
               {
                  _loc5_ = _loc3_[_loc4_];
                  this.destroyNode(_loc5_);
                  _loc4_++;
               }
            }
            _loc2_++;
         }
         this._lineInfo.length = 0;
      }
      
      private function clear() : void
      {
         this.resetLines();
         _textField.htmlText = "";
         _textField.defaultTextFormat = _textFormat;
         this._objectsContainer.removeChildren();
         this._needUpdateNodePos = false;
      }
      
      private function fixTextSize() : void
      {
         _textField.textWidth;
         _textField.height;
      }
      
      private function isLineVisible(param1:int) : Boolean
      {
         return true;
      }
      
      private function createNode(param1:int) : EHtmlNode
      {
         var _loc3_:EHtmlNode = null;
         var _loc2_:Vector.<EHtmlNode> = this._lineInfo[param1];
         if(!_loc2_)
         {
            _loc2_ = new Vector.<EHtmlNode>();
            this._lineInfo[param1] = _loc2_;
         }
         if(this._nodeCache.length)
         {
            _loc3_ = this._nodeCache.pop();
         }
         else
         {
            _loc3_ = new EHtmlNode();
         }
         _loc3_.lineIndex = param1;
         _loc3_.nodeIndex = _loc2_.length;
         _loc2_.push(_loc3_);
         return _loc3_;
      }
      
      private function destroyNode(param1:EHtmlNode) : void
      {
         if(param1.displayObject != null)
         {
            if(param1.displayObject.parent != null)
            {
               this._objectsContainer.removeChild(param1.displayObject);
            }
            if(param1.element.type == EHtmlElement.LINK)
            {
               this._linkButtonCache.push(param1.displayObject);
            }
            else if(param1.element.type == EHtmlElement.IMAGE)
            {
               EUISprite(param1.displayObject).owner.dispose();
            }
         }
         param1.reset();
         this._nodeCache.push(param1);
      }
      
      private function addLink(param1:int, param2:EHtmlElement) : void
      {
         var _loc7_:int = 0;
         var _loc8_:int = 0;
         var _loc3_:int = param1 + param2.start;
         var _loc4_:int = param1 + param2.end;
         var _loc5_:int = _textField.getLineIndexOfChar(_loc3_);
         var _loc6_:int = _textField.getLineIndexOfChar(_loc4_);
         if(_loc5_ == _loc6_)
         {
            this.addLinkButton(_loc5_,_loc3_,_loc4_,param2);
         }
         else
         {
            _loc7_ = _textField.getLineOffset(_loc5_);
            this.addLinkButton(_loc5_,_loc3_,_loc7_ + _textField.getLineLength(_loc5_) - 1,param2);
            _loc8_ = _loc5_ + 1;
            while(_loc8_ < _loc6_)
            {
               _loc7_ = _textField.getLineOffset(_loc8_);
               this.addLinkButton(_loc8_,_loc7_,_loc7_ + _textField.getLineLength(_loc8_) - 1,param2);
               _loc8_++;
            }
            this.addLinkButton(_loc6_,_textField.getLineOffset(_loc6_),_loc4_,param2);
         }
      }
      
      private function addLinkButton(param1:int, param2:int, param3:int, param4:EHtmlElement) : void
      {
         param2 = this.skipLeftCR(param2,param3);
         param3 = this.skipRightCR(param2,param3);
         var _loc5_:EHtmlNode = this.createNode(param1);
         _loc5_.charStart = param2;
         _loc5_.charEnd = param3;
         _loc5_.element = param4;
         if(this.isLineVisible(param1))
         {
            this.showNode(_loc5_);
         }
      }
      
      private function addImage(param1:int, param2:EHtmlElement) : void
      {
         var _loc3_:int = param1 + param2.start;
         var _loc4_:int = _textField.getLineIndexOfChar(_loc3_);
         var _loc5_:EHtmlNode = this.createNode(_loc4_);
         _loc5_.charStart = _loc3_;
         _loc5_.charEnd = _loc3_;
         _loc5_.element = param2;
         if(this.isLineVisible(_loc4_))
         {
            this.showNode(_loc5_);
         }
      }
      
      private function showNode(param1:EHtmlNode) : void
      {
         var _loc3_:ELinkButton = null;
         var _loc4_:Rectangle = null;
         var _loc5_:Rectangle = null;
         var _loc6_:int = 0;
         var _loc7_:int = 0;
         var _loc8_:TextLineMetrics = null;
         var _loc9_:EGLoader = null;
         var _loc2_:EHtmlElement = param1.element;
         if(_loc2_.type == EHtmlElement.LINK)
         {
            if(param1.displayObject == null)
            {
               if(this._linkButtonCache.length)
               {
                  _loc3_ = this._linkButtonCache.pop();
               }
               else
               {
                  _loc3_ = new ELinkButton();
               }
               _loc3_.owner = param1;
               param1.displayObject = _loc3_;
            }
            if(!param1.posUpdated)
            {
               _loc4_ = _textField.getCharBoundaries(param1.charStart);
               if(_loc4_ == null)
               {
                  return;
               }
               _loc5_ = _textField.getCharBoundaries(param1.charEnd);
               if(_loc5_ == null)
               {
                  return;
               }
               _loc6_ = _loc5_.right - _loc4_.left;
               if(_loc4_.left + _loc6_ > _textField.width - 2)
               {
                  _loc6_ = _textField.width - _loc4_.left - 2;
               }
               _loc7_ = Math.max(_loc4_.height,_loc5_.height);
               param1.displayObject.x = _loc4_.left;
               param1.displayObject.width = _loc6_;
               param1.displayObject.height = _loc7_;
               if(_loc4_.top < _loc5_.top)
               {
                  param1.topY = 0;
               }
               else
               {
                  param1.topY = _loc5_.top - _loc4_.top;
               }
               param1.posUpdated = true;
            }
            else
            {
               _loc4_ = _textField.getCharBoundaries(param1.charStart);
               if(_loc4_ == null)
               {
                  return;
               }
            }
            param1.displayObject.y = _loc4_.top + param1.topY;
            if(param1.displayObject.parent == null)
            {
               this._objectsContainer.addChild(param1.displayObject);
            }
         }
         else if(_loc2_.type == EHtmlElement.IMAGE)
         {
            if(param1.displayObject == null)
            {
               _loc9_ = EGLoader(EUIObjectFactory.createObject2(this.pkg,"loader",editMode == 1?1:0));
               _loc9_.fill = "scaleFree";
               _loc9_.url = _loc2_.src;
               _loc9_.width = _loc2_.realWidth;
               _loc9_.height = _loc2_.realHeight;
               param1.displayObject = _loc9_.displayObject;
            }
            _loc4_ = _textField.getCharBoundaries(param1.charStart);
            if(_loc4_ == null)
            {
               return;
            }
            _loc8_ = _textField.getLineMetrics(param1.lineIndex);
            if(_loc8_ == null)
            {
               return;
            }
            param1.displayObject.x = _loc4_.left + 2;
            if(_loc2_.realHeight < _loc8_.ascent)
            {
               param1.displayObject.y = _loc4_.top + _loc8_.ascent - _loc2_.realHeight;
            }
            else
            {
               param1.displayObject.y = _loc4_.bottom - _loc2_.realHeight;
            }
            if(param1.displayObject.x + param1.displayObject.width < _textField.width - 2)
            {
               if(param1.displayObject.parent == null)
               {
                  this._objectsContainer.addChildAt(param1.displayObject,this._objectsContainer.numChildren);
               }
            }
         }
      }
      
      private function hideNode(param1:EHtmlNode) : void
      {
         if(param1.displayObject && param1.displayObject.parent)
         {
            this._objectsContainer.removeChild(param1.displayObject);
         }
      }
      
      private function skipLeftCR(param1:int, param2:int) : int
      {
         var _loc5_:String = null;
         var _loc3_:String = _textField.text;
         var _loc4_:int = param1;
         while(_loc4_ < param2)
         {
            _loc5_ = _loc3_.charAt(_loc4_);
            if(_loc5_ != "\r" && _loc5_ != "\n")
            {
               break;
            }
            _loc4_++;
         }
         return _loc4_;
      }
      
      private function skipRightCR(param1:int, param2:int) : int
      {
         var _loc5_:String = null;
         var _loc3_:String = _textField.text;
         var _loc4_:int = param2;
         while(_loc4_ > param1)
         {
            _loc5_ = _loc3_.charAt(_loc4_);
            if(_loc5_ != "\r" && _loc5_ != "\n")
            {
               break;
            }
            _loc4_--;
         }
         return _loc4_;
      }
   }
}
